import sys
from copy import deepcopy
from numpy import *

from common import *

class Board:
    def __init__(self, size):
        self.size = size
        self.numberDropped = 0
        self.clear()

    def clear(self):
        self.board = zeros( (self.size, self.size), dtype=int16)
        self.numberDropped = 0
        self.latestMove = (-1, -1)
        
    def __str__(self):
        s = ""
        for i in range(self.size):
            for j in range(self.size):
                x = j
                y = self.size - i - 1
                if self.board[x,y] == 0:
                    s = s + " "
                elif self.board[x,y] == 1:
                    s = s + "+"
                elif self.board[x,y] == 2:
                    s = s + "*"
            if i < self.size - 1:
                s = s + "\n"
        return s
        
    def printMe(self):
        for i in range(self.size):
            for j in range(self.size):
                x = j
                y = self.size - i - 1
                if self.board[x,y] == 0:
                    sys.stdout.write(" ")
                elif self.board[x,y] == 1:
                    sys.stdout.write("+")
                elif self.board[x,y] == 2:
                    sys.stdout.write("*")
            print ""

## start Minimax interface            
    
    def terminal_test(self):
        if self.checkWin()[0] != 0:
            return True
        return False
            
    def generate_moves(self):
        return self.notFullColumns()
        
    def copy(self):
        return deepcopy(self)
    
    def score(self, value):
        win = self.checkWin()
        if win[0] == value: # I won
            return 1.0
        if win[0] != 0: # other player won
            return -1.0
        return 0.0
        
## end Minimax interface            
        
    def drop(self, slot, value):
        self.numberDropped = self.numberDropped + 1
        for i in range(0,self.size):
            if self.board[slot, i] == 0:
                self.board[slot, i] = value
                self.latestMove = (slot, value)
                return
        print "ERROR: Line is full"
        sys.exit()
    
    def checkWinAtPos(self, x, y):
        value = self.board[x, y]
        if value == 0:
            return 0
        win = True
        if y + 4 <= self.size:
            for i in range(1,4):
                if self.board[x, y+i] != value:
                    win = False
                    break
            if win:
                return value
        if x + 4 <= self.size:
            win = True
            for i in range(1,4):
                if self.board[x+i, y] != value:
                    win = False
                    break
            if win:
                return value
            if y + 4 <= self.size:
                win = True
                for i in range(1,4):
                    if self.board[x+i, y+i] != value:
                        win = False
                        break
                if win:
                    return value
        return 0
            
    def notFullColumns(self):
        columns = []
        for i in range(self.size):
            if self.board[i, self.size-1] == 0:
                columns.append(i)
        return columns
    
    def checkWin(self):
        if self.numberDropped < 4:
            return (0, -1, -1)
        win = 0
        for i in range(self.size):
            for j in range(self.size):
                winner = self.checkWinAtPos(i, j)
                if winner != 0:
                    return (winner, i, j)
        return (0, -1, -1)
